#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Servo.h> // 声明调用Servo.h库
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <U8g2lib.h>
#include <Wire.h>
#include "DHT.h"


// WiFi
const char *ssid = "rabbit"; // WiFi name
const char *password = "96789471";  //WiFi password

// MQTT Broker
const char *mqtt_broker = "192.168.43.253";
const char *topic_l = "565402462_ESP";
const char *topic_window = "window_c";
const char *topic_fan = "fan_c";
const char *topic_humi = "humidity";
const char *topic_temp = "temeperature";
const char *mqtt_username = "emqx";
const char *mqtt_password = "public";
const char *topic_rain = "rain";
const int mqtt_port = 1883;
int ledPin = 15;
int relayPin = 4;
int enginePin = 0;
int rainPin = A0;
int rainValue = 0;
//烟雾
int smokePin = 5;//D1
int smoke_value ;



//舵机
Servo myservo; // 舵机对象
int pos = 0; // 舵机位置

//TempDHTsensor
#define DHTPIN  2
#define DHTTYPE DHT11
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
DHT dht(DHTPIN, DHTTYPE);

WiFiClient espClient;
PubSubClient client(espClient);



void setup() {
  u8g2.begin();
  dht.begin();

  myservo.attach(0);
  myservo.write(0);

  pinMode(smokePin, INPUT);

  //卧室灯
  pinMode(ledPin, OUTPUT);
  pinMode(relayPin, OUTPUT);
  //设置软件端口的波特率
  Serial.begin(115200);
  //连接到WiFi网络
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting to WiFi..");
  }
  Serial.println("Connected to the WiFi network");

  //连接到mqtt服务器
  client.setServer(mqtt_broker, mqtt_port);
  client.setCallback(callback);
  while (!client.connected()) {
    String client_id = "esp8266-client-";
    client_id += String(WiFi.macAddress());
    Serial.printf("The client %s connects to the public mqtt broker\n", client_id.c_str());
    if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
      Serial.println("Public emqx mqtt broker connected");
    } else {
      Serial.print("failed with state ");
      Serial.print(client.state());
      delay(2000);
    }
  }
  // 发布消息和订阅消息

  client.subscribe(topic_l);
  client.subscribe(topic_window);
  client.subscribe(topic_fan);
}

void callback(char *topic, byte *payload, unsigned int length) {
  char* topic_pub1 = "565402462_ESP";
  byte first[] = {0x6C, 0x65, 0x64, 0x4F, 0x6E}; //ledon
  //继电器控制
  if (!strcmp(topic, topic_fan)) {
    if (payload[4] == 0x6E) {
      digitalWrite(relayPin, HIGH);
    } else {
      digitalWrite(relayPin, LOW);
    }
  }
  //灯控制
  if (!strcmp(topic, topic_l)) {
    if (payload[4] == 0x6E) {
      digitalWrite(ledPin, HIGH);
    } else {
      digitalWrite(ledPin, LOW);
    }
  }

  //舵机控制
  if (!strcmp(topic, topic_window)) {
    Serial.print(payload[7]);//打开窗户
    if (payload[7] == 0x6f) {
      myservo.write(180);
    } else {
      myservo.write(0); // 给舵机写入角度
    }
  }


  Serial.print("Message arrived in topic: ");
  Serial.println(topic);
  Serial.print("Message:");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
    Serial.println(payload[i]);
  }
  Serial.println();
  Serial.println("-----------------------");
}
char h_str[5];
char t_str[5];
float h;
float t;



void loop() {
  client.loop();

  smoke_value = digitalRead(smokePin);
  Serial.print("smoke_value:");
  Serial.println(smoke_value);
  if (smoke_value == HIGH) {
    //低电平代表气体浓度超过上限
    Serial.println("Smoke status is fine");
  } else {
    digitalWrite(relayPin, HIGH);
    myservo.write(180);
    delay(5000);
    digitalWrite(relayPin, LOW);
    myservo.write(0);
  }

  rainValue = analogRead(rainPin);
  Serial.print("raindrop：");
  Serial.println(rainValue);
  // if (rainValue <= 850) {
  //   client.publish(topic_rain, "window_close" );
  //   myservo.write(0);
  // }



  char humi[50];
  h = dht.readHumidity();//读湿度
  strcpy(humi, ((String)h).c_str());
  Serial.println("starting to send data");
  //client.publish(topic_temp,"hello temo");
  client.publish(topic_humi, humi );
  Serial.println(humi);
  Serial.print("humidity：");
  Serial.println(h);

  char temp[50];
  t = dht.readTemperature();//读温度(摄氏度)
  strcpy(temp, ((String)t).c_str());
  client.publish(topic_temp, temp );
  Serial.print("temprature：");
  Serial.println(t);
  Serial.println();
  delay(1000);
}